/*
 * XMinimizablePanel.java
 * 
 * Copyright (c) 2006 - 2007
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.xfc.components;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.PopupMenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.border.Border;

import org.xfc.XApp;
import org.xfc.util.XResources;

import com.jgoodies.forms.layout.FormLayout;

// TODO: should we really be delegating through to the content panel? Or just let the user take care of that?

// TODO: animated collapse / expand effect?

// TODO: visible reminder that there is contents in a collapsed panel? ellipses? a faint gray box outline?


/**
 * 
 * 
 * @author Devon Carew
 */
public class XMinimizablePanel
	extends JPanel
{
	private JPanel 		contentPanel = new JPanel();
	private XIconButton	disclosureButton;
	private JLabel		titleLabel;
	
	private static ImageIcon	openIcon;
	private static ImageIcon	closeIcon;
	
	static
	{
		XResources resources = XApp.getApp().getResources();
		
		openIcon = resources.getIcon("/firefox/skin/classic/global/tree/twisty-clsd.png");
		closeIcon = resources.getIcon("/firefox/skin/classic/global/tree/twisty-open.png");
	}
	
	/**
	 * Create a new minimizable panel.
	 */
	public XMinimizablePanel()
	{
		disclosureButton = new XIconButton(closeIcon);
		disclosureButton.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
		disclosureButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				toggleButton();
			}
		});
		
		titleLabel = new JLabel();
		titleLabel.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent event) {
				toggleButton();
			}
		});
		
		JSeparator separator = new JSeparator(JSeparator.HORIZONTAL);
		
		// Width is the same as the content panel. This prevents horizontal resizing when the content
		// panel is shown / hidden.
		JComponent spacer = new JComponent() {
			public Dimension getMinimumSize() {
				return new Dimension(contentPanel.getMinimumSize().width, 1);
			}
			public Dimension getPreferredSize() {
				return new Dimension(contentPanel.getPreferredSize().width, 1);
			}
		};
		
		super.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
		super.setLayout(new FormLayout(
			"pref 1dlu pref 3dlu pref:grow",
			"pref 2dlu pref:grow"
		));
		
		super.add(disclosureButton, "1, 1, c, c");
		super.add(titleLabel, 		"3, 1, c, c");
		super.add(separator, 		"5, 1, f, c");
		super.add(spacer, 			"3, 2, 3, 1, f, c");
		super.add(contentPanel, 	"3, 3, 3, 1, f, f");
		
		contentPanel.setVisible(!isMinimized());
	}
	
	/**
	 * Create a new minimizable panel with the given title.
	 * 
	 * @param title the title for the minimizable panel
	 */
	public XMinimizablePanel(String title)
	{
		this();
		
		setTitle(title);
	}
	
	/**
	 * Create a new minimizable panel, using the given layout manager for the embedded content panel.
	 * 
	 * @param layout the layout manager to use for the embedded content panel
	 */
	public XMinimizablePanel(LayoutManager layout)
	{
		this();
		
		setLayout(layout);
	}
	
	public String getTitle()
	{
		return titleLabel.getText();
	}
	
	public void setTitle(String title)
	{
		String oldValue = getTitle();
		titleLabel.setText(title);
		firePropertyChange("title", oldValue, getTitle());
	}
	
	public boolean isMinimized()
	{
		return disclosureButton.getIcon() == openIcon;
	}
	
	public void setMinimized(boolean value)
	{
		if (isMinimized() == value)
			return;
		
		boolean oldValue = isMinimized();
		
		if (value)
		{
			// Set the panel to the minimized state.
			disclosureButton.setIcon(openIcon);
			contentPanel.setVisible(false);
		}
		else
		{
			// Set the panel to the non-minimized state.
			disclosureButton.setIcon(closeIcon);
			contentPanel.setVisible(true);
		}
		
		firePropertyChange("minimized", oldValue, isMinimized());
	}
	
	private void toggleButton()
	{
		setMinimized(!isMinimized());
	}
	
	/**
	 * @return the actual content panel for this minimizable panel
	 */
	public JPanel getContentPanel()
	{
		return contentPanel;
	}
	
	public Component add(Component comp, int index)
	{
		return contentPanel.add(comp, index);
	}
	
	public void add(Component comp, Object constraints, int index)
	{
		contentPanel.add(comp, constraints, index);
	}
	
	public void add(Component comp, Object constraints)
	{
		contentPanel.add(comp, constraints);
	}
	
	public Component add(Component comp)
	{
		return contentPanel.add(comp);
	}
	
	public void add(PopupMenu popup)
	{
		contentPanel.add(popup);
	}
	
	public Component add(String name, Component comp)
	{
		return contentPanel.add(name, comp);
	}
	
	public void remove(Component comp)
	{
		contentPanel.remove(comp);
	}
	
	public void remove(int index)
	{
		contentPanel.remove(index);
	}
	
	public void setBorder(Border border)
	{
		if (contentPanel == null)
			super.setBorder(border);
		else
			contentPanel.setBorder(border);
	}
	
	public void setLayout(LayoutManager layout)
	{
		if (contentPanel == null)
			super.setLayout(layout);
		else
			contentPanel.setLayout(layout);
	}
	
	public void setToolTipText(String text)
	{
		super.setToolTipText(text);
		
		disclosureButton.setToolTipText(text);
		titleLabel.setToolTipText(text);
	}
	
}
